package com.example.gw_back_end.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.gw_back_end.domain.PageParam;
import com.example.gw_back_end.domain.PageResult;
import com.example.gw_back_end.domain.SearchParams;
import com.example.gw_back_end.domain.entities.*;
import com.example.gw_back_end.mapper.*;
import com.example.gw_back_end.service.PostService;
import com.example.gw_back_end.utils.ThreadLocalUtil;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService {

    private final PostMapper postMapper;
    private final PostCommentMapper postCommentMapper;
    private final UserMapper userMapper;
    private final PostViewMapper postViewMapper;
    private final PostLikeMapper postLikeMapper;
    public PostServiceImpl(PostMapper postMapper, PostCommentMapper postCommentMapper,UserMapper userMapper, PostViewMapper postViewMapper, PostLikeMapper postLikeMapper) {
        this.postMapper = postMapper;
        this.postCommentMapper = postCommentMapper;
        this.userMapper = userMapper;
        this.postViewMapper = postViewMapper;
        this.postLikeMapper = postLikeMapper;
    }

    // 分页获取帖子列表
    @Override
    public PageResult<Post> getPostList(PageParam pageParam) {
        LambdaQueryWrapper<Post> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(Post::getCreateTime);

        Page<Post> postPage = postMapper.selectPage(new Page<>(pageParam.getPage(),pageParam.getSize()),/*queryWrapper*/lambdaQueryWrapper);

        Set<Integer> userIdList = postPage.getRecords().stream()
                .map(Post::getUserId)
                .collect(Collectors.toSet());

        Set<Integer> postIdList = postPage.getRecords().stream()
                .map(Post::getId)
                .collect(Collectors.toSet());

        Map<Integer, User> userMap = userMapper.selectBatchIds(userIdList)
                .stream()
                .collect(Collectors.toMap(User::getId, Function.identity()));

        Map<Integer, Long> postCommentCountMap = postCommentMapper.selectList(
                        new LambdaQueryWrapper<PostComment>()
                                .in(PostComment::getPostId, postIdList)
                ).stream()
                .collect(Collectors.groupingBy(
                        PostComment::getPostId,
                        Collectors.counting()
                ));

        postPage.getRecords().forEach(post -> {
            User user = userMap.get(post.getUserId());
            if (user != null) {
                post.setUsername(user.getUsername());
                post.setAvatar(user.getAvatar());
            }
            post.setCommentCount(
                    postCommentCountMap.getOrDefault(post.getId(), 0L).intValue()
            );
            post.setViewCount(postViewMapper.selectViewCount(post.getId()));
            LambdaQueryWrapper<PostLike> postLikeLambdaQueryWrapper = new LambdaQueryWrapper<>();
            postLikeLambdaQueryWrapper.eq(PostLike::getPostId, post.getId());
            post.setLikeCount(postLikeMapper.selectCount(postLikeLambdaQueryWrapper).intValue());
        });

        return PageResult.setPageResult(postPage);
    }

    // 新增帖子
    @Override
    public boolean addPost(Post post) {
        Map<String,Object> claims = ThreadLocalUtil.get();
        Integer id = (Integer) claims.get("id");
        post.setUserId(id);
        post.setCreateTime(LocalDateTime.now());
        post.setUpdateTime(LocalDateTime.now());
        post.setStatus(1);
        return postMapper.insert(post) > 0;
    }

    // 删除帖子
    @Override
    public boolean deletePost(Integer id) {
        return postMapper.deleteById(id) > 0;
    }

    // 获取帖子
    @Override
    public Post getPostById(Integer id,String clientType) {
        Post post = postMapper.selectById(id);
        User user = userMapper.selectById(post.getUserId());
        post.setUsername(user.getUsername());
        post.setAvatar(user.getAvatar());
        post.setCommentCount(
                postCommentMapper.selectCount(
                        new LambdaQueryWrapper<PostComment>().eq(PostComment::getPostId, post.getId())
                ).intValue()
        );
        LambdaQueryWrapper<PostLike> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PostLike::getPostId, post.getId());
        post.setLikeCount(postLikeMapper.selectCount(lambdaQueryWrapper).intValue());
        post.setViewCount(postViewMapper.selectViewCount(id));
        if (clientType.equals("Client") && postViewMapper.exists(new LambdaQueryWrapper<PostView>().eq(PostView::getPostId, id))) {
            postViewMapper.updateViewCount(id);
        } else if (clientType.equals("Client") && !postViewMapper.exists(new LambdaQueryWrapper<PostView>().eq(PostView::getPostId, id))) {
            PostView postView = new PostView();
            postView.setPostId(id);
            if (postViewMapper.insert(postView) > 0) {
                postViewMapper.updateViewCount(id);
            }
        }
        return post;
    }

    // 更新帖子
    @Override
    public boolean updatePost(Post post) {
        post.setUpdateTime(LocalDateTime.now());
        return postMapper.updateById(post) > 0;
    }

    @Override
    public PageResult<Post> searchPost(SearchParams searchParams) {
        String keyword = searchParams.getKeyword();
        LambdaQueryWrapper<Post> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(Post::getTitle, keyword)/*.or().like(Post::getContent, keyword)*/;
        Page<Post> postPage = postMapper.selectPage(new Page<>(searchParams.getPageParam().getPage(),searchParams.getPageParam().getSize()),lambdaQueryWrapper);
        return PageResult.setPageResult(postPage);
    }
}
